﻿using System;
using System.IO;

namespace Netfraction.Common.DataStorage
{
    public class TextDataStore : DataStore, IDataStore
    {
        /// <summary>
        /// Creates a new TextDataStore instance.
        /// </summary>
        /// <param name="owner"></param>
        public TextDataStore(DataSource owner)
            : base(owner)
        {
            this.DataStoreType = DataStoreType.TextFile;
        }

        /// <summary>
        /// Creates a new TextDataStore instance and the specified data store. Does not overwrite an existing store.
        /// </summary>
        /// <param name="owner"></param>
        /// <param name="storeName"></param>
        public TextDataStore(DataSource owner, string storeName)
            : base(owner)
        {
            this.DataStoreType = DataStoreType.TextFile;
            this.DataStoreName = storeName;

            Create(storeName, false);
        }

        public bool Create(string name, bool overwrite)
        {
            if (!CheckBasePath(name))
                return false;

            if (!overwrite && File.Exists(Path.Combine(this.BasePath, name)))
                return true;

            if (!Directory.Exists(Path.GetDirectoryName(Path.Combine(this.BasePath, name))))
                Directory.CreateDirectory(Path.GetDirectoryName(Path.Combine(this.BasePath, name)));

            FileStream f = File.Create(Path.Combine(this.BasePath, name));
            f.Close();
            this.DataStoreName = name;

            return true;
        }

        public StreamReader CreateReader()
        {
            if (!CheckFileExists())
                return null;

            try
            {
                return new StreamReader(new FileStream(this.FullPath, FileMode.Open, FileAccess.Read, FileShare.Read));
            }
            catch (FileNotFoundException fnfex)
            {
                Netfraction.Common.Logging.LogManager.WriteEntry(fnfex.Message, Netfraction.Common.Logging.LogEntryType.Error, Netfraction.Common.Logging.LogEventId.TextStoreException, Netfraction.Common.Logging.LogLevel.Detailed);
                return null;
            }
            catch (Exception ex)
            {
                Netfraction.Common.Logging.LogManager.WriteEntry(ex.Message, Netfraction.Common.Logging.LogEntryType.Error, Netfraction.Common.Logging.LogEventId.TextStoreException, Netfraction.Common.Logging.LogLevel.Detailed);
                return null;
            }
        }

        public StreamWriter CreateWriter(bool append)
        {
            if (!CheckFileExists())
                return null;

            try
            {
                if (append)
                    return new StreamWriter(new FileStream(this.FullPath, FileMode.Append, FileAccess.Write, FileShare.None));
                else
                    return new StreamWriter(new FileStream(this.FullPath, FileMode.Create, FileAccess.Write, FileShare.None));
            }
            catch (FileNotFoundException fnfex)
            {
                Netfraction.Common.Logging.LogManager.WriteEntry(fnfex.Message, Netfraction.Common.Logging.LogEntryType.Error, Netfraction.Common.Logging.LogEventId.TextStoreException, Netfraction.Common.Logging.LogLevel.Detailed);
                return null;
            }
            catch (Exception ex)
            {
                Netfraction.Common.Logging.LogManager.WriteEntry(ex.Message, Netfraction.Common.Logging.LogEntryType.Error, Netfraction.Common.Logging.LogEventId.TextStoreException, Netfraction.Common.Logging.LogLevel.Detailed);
                return null;
            }
        }

        public bool IsEmpty()
        {
            FileInfo f = new FileInfo(this.FullPath);

            if (f.Length == 0)
                return true;
            else
                return false;
        }

        private bool CheckFileExists()
        {
            if (string.IsNullOrEmpty(this.DataStoreName))
                return false;

            if (!File.Exists(this.FullPath) && !Create(this.DataStoreName, false))
                return false;

            return true;
        }

        public bool Delete()
        {
            if (this.DataStoreName == string.Empty)
                return false;

            File.Delete(this.FullPath);

            return File.Exists(this.FullPath);
        }
    }
}
